package com.ph.finder.client.mapper.ui;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.maps.client.MapType;
import com.google.gwt.maps.client.MapUIOptions;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.Size;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.ph.finder.client.AddressInfo;
import com.ph.finder.client.BreadCrumbManager;
import com.ph.finder.client.CityItem;
import com.ph.finder.client.PrecinctService;
import com.ph.finder.client.PrecinctServiceAsync;
import com.ph.finder.client.Util;
import com.ph.finder.client.ui.MainShell;

public class MapPrecinctRootPage extends Composite {

	private static MapPrecinctRootPageUiBinder uiBinder = GWT
			.create(MapPrecinctRootPageUiBinder.class);

	interface MapPrecinctRootPageUiBinder extends
			UiBinder<Widget, MapPrecinctRootPage> {
	}

	@UiField
	SimplePanel leftSide;

	@UiField
	FlowPanel bottomLeftSide;

	@UiField
	MapWidget maps;

	private final MainShell ctr;

	private CityItem citySelection;

	private final BreadCrumbManager breadCrumb;

	public MapPrecinctRootPage(MainShell ctr, BreadCrumbManager breadCrumb) {
		this.ctr = ctr;
		this.breadCrumb = breadCrumb;
		initWidget(uiBinder.createAndBindUi(this));

		initializeBreadCrumbs();
		initializeMaps();

		// Show City Selection Panel
		swapLeftPanel(new CitySelectLPanel(this, maps));
	}

	private void initializeMaps() {
		MapUIOptions options = MapUIOptions.newInstance(Size.newInstance(450, 300));
		options.setScaleControl(true);
		maps.setUI(options);
		for(MapType type : MapType.getDefaultMapTypes()) {
			maps.removeMapType(type);
		}
		maps.removeMapType(MapType.getPhysicalMap());
		maps.addMapType(MapType.getMapMakerNormalMap());
		maps.addMapType(MapType.getMapMakerHybridMap());

		maps.setCenter(LatLng.newInstance(11.781, 122.695), 5, MapType.getMapMakerHybridMap());
	}

	protected void selectAddressInList(CityItem selection, List<AddressInfo> results) {
		this.citySelection = selection;
//		ctr.setHeight("550px");

		swapLeftPanel(new PrecinctSelectLPanel(this, results));

		// Initialize cancel Bread crumb
		breadCrumb.pushEntry(selection.getReplacementString(),
				new Runnable() {
			@Override
			public void run() {
				PrecinctServiceAsync service = (PrecinctServiceAsync) GWT.create(PrecinctService.class);
				service.getAddressesOnCity(citySelection.getRegion(),
						citySelection.getProvinceKey(),
						citySelection.getCityKey(),
						true,
						false,
						20,
						new AsyncCallback<List<AddressInfo>>() {

					@Override
					public void onSuccess(List<AddressInfo> results) {
						Util.track("/MapYourPrecinct/04-AreaUnmapped");
						if (results == null || results.size() == 0) {
							breadCrumb.popEntry();
						} else {
							// Actually show next panel UI
							swapLeftPanel(new PrecinctSelectLPanel(MapPrecinctRootPage.this, results));
						}
					}

					@Override
					public void onFailure(Throwable caught) {
						Util.track("/MapYourPrecinct/04-AreaUnmappedFail");
						breadCrumb.popEntry();
					}
				});
			}
		},
				new Runnable() {
			@Override
			public void run() {
//				ctr.setHeight("440px");
				bottomLeftSide.clear();
			}
		});
	}

	public void mapAddress(AddressInfo addressInfo) {
		// Actually show next panel UI
		leftSide.remove(leftSide.getWidget());
		maps.setWidth("782px");

		AddressMappingBLPanel panel = new AddressMappingBLPanel(this, addressInfo, maps, breadCrumb);
		bottomLeftSide.add(panel);
		bottomLeftSide.setVisible(true);

		// Initialize cancel Bread crumb
		breadCrumb.pushEntry("Map a Precinct",
				new Runnable() {
			@Override
			public void run() {
				new RuntimeException("This will never happen.");
			}
		},
				new Runnable() {
			@Override
			public void run() {
				bottomLeftSide.setVisible(false);
				bottomLeftSide.clear();
				maps.setWidth("400px");
			}
		});
	}

	private void initializeBreadCrumbs() {
		breadCrumb.pushEntry("Map Precinct",
				new Runnable() {
			@Override
			public void run() {
				swapLeftPanel(new CitySelectLPanel(MapPrecinctRootPage.this, maps));
			}
		},
				new Runnable() {
			@Override
			public void run() {
				bottomLeftSide.clear();
			}
		});
	}

	private void swapLeftPanel(Widget page) {
		if (leftSide.getWidget() != null) {
			leftSide.remove(leftSide.getWidget());
		}
		leftSide.add(page);
	}

}
